package com.nbcio.online.service.impl;

import java.util.Map;

import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.io.UnsupportedEncodingException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import com.alibaba.fastjson.JSONObject;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nbcio.common.core.utils.StringUtils;
import com.nbcio.common.mybatis.core.page.PageQuery;
import com.nbcio.common.mybatis.core.page.TableDataInfo;
import com.nbcio.common.satoken.utils.LoginHelper;
import com.nbcio.common.tenant.helper.TenantHelper;
import com.nbcio.generator.domain.GenTable;
import com.nbcio.generator.domain.GenTableColumn;
import com.nbcio.generator.mapper.GenTableMapper;
import com.nbcio.generator.service.IGenTableService;
import com.nbcio.online.domain.vo.DictVo;
import com.nbcio.online.domain.vo.OnlFieldVo;
import com.nbcio.online.domain.vo.TableVo;
import com.nbcio.online.mapper.OnlineMapper;
import com.nbcio.online.service.IFormService;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;


/**
 * online表单 服务层实现
 *
 * @author nbacheng
 */

@Slf4j
@RequiredArgsConstructor
@Service
public class FormServiceImpl implements IFormService {
	
	private final GenTableMapper baseMapper;
	private final IGenTableService genTableService;
	private final OnlineMapper onlineMapper;
	
	@Override
	public Map<String, Object> getOnlineForm(Long tableId) {
		GenTable table = genTableService.selectGenTableById(tableId);
		List<GenTableColumn> columnsList = table.getColumns();
		TableVo tableVo = new TableVo();
		List<OnlFieldVo> columnsListCopy = new ArrayList<OnlFieldVo>();
		BeanUtils.copyProperties(table, tableVo);
		for (GenTableColumn tablecolumn : columnsList) {
			OnlFieldVo onlFieldVo = new OnlFieldVo();
			BeanUtils.copyProperties(tablecolumn, onlFieldVo);
			columnsListCopy.add(onlFieldVo);
		}
		List<OnlFieldVo> newColumnsList = new ArrayList<OnlFieldVo>();
		if (columnsListCopy.size() > 0 ) {
			//去除不必要的数据字段信息
            for(int i=0;i<columnsListCopy.size();i++){
            	if(!columnsListCopy.get(i).getColumnName().equalsIgnoreCase("create_dept") &&
            	   !columnsListCopy.get(i).getColumnName().equalsIgnoreCase("create_by") &&
            	   !columnsListCopy.get(i).getColumnName().equalsIgnoreCase("create_time") &&
            	   !columnsListCopy.get(i).getColumnName().equalsIgnoreCase("update_by") &&
            	   !columnsListCopy.get(i).getColumnName().equalsIgnoreCase("update_time") ) {
            		if (ObjectUtils.isNotEmpty(getColumnDict(columnsList.get(i)))) {
            			columnsListCopy.get(i).setCommonDictCode(getColumnDict(columnsListCopy.get(i)));
            		}
            		newColumnsList.add(columnsListCopy.get(i));
            	}
            }
		}
		tableVo.setColumnsVo(newColumnsList);
        Map<String, Object> map = new HashMap<>(1);
        map.put("info", tableVo);
        return map;
	}

	@Override
	public TableDataInfo<GenTable> selectPageGenTableList(GenTable genTable, PageQuery pageQuery) {
		Page<GenTable> page = baseMapper.selectPage(pageQuery.build(), this.buildGenTableQueryWrapper(genTable));
        return TableDataInfo.build(page);
	}
	
	private QueryWrapper<GenTable> buildGenTableQueryWrapper(GenTable genTable) {
        Map<String, Object> params = genTable.getParams();
        QueryWrapper<GenTable> wrapper = Wrappers.query();
        wrapper
            .eq(StringUtils.isNotEmpty(genTable.getDataName()),"data_name", genTable.getDataName())
            .like(StringUtils.isNotBlank(genTable.getTableName()), "lower(table_name)", StringUtils.lowerCase(genTable.getTableName()))
            .like(StringUtils.isNotBlank(genTable.getTableComment()), "lower(table_comment)", StringUtils.lowerCase(genTable.getTableComment()))
            .between(params.get("beginTime") != null && params.get("endTime") != null,
                "create_time", params.get("beginTime"), params.get("endTime"));
        return wrapper;
    }
	
    public  List<DictVo> getColumnDict(GenTableColumn onlColumn){
    	String dictType = onlColumn.getDictType();
    	if (StringUtils.isNotEmpty(dictType)) {
    		List<DictVo> dictVoList = onlineMapper.getDictData(dictType, TenantHelper.getTenantId());
    		return dictVoList;
    	}
		return null;
    }

	@Override
	public TableDataInfo<Map> listOnlineData(Long tableId, String tableName, PageQuery pageQuery) {
		QueryWrapper<Map> wrapper = Wrappers.query();
		wrapper.eq("tenant_id", TenantHelper.getTenantId());
		JSONObject params = pageQuery.getParams();
		if (ObjectUtils.isNotEmpty(params)) {
			//遍历查询JSON对象
			for(String key : params.keySet()) {
				Object queryValue = params.get(key);
				wrapper.eq(key,queryValue);
			}
		}
		Page<Map> page = onlineMapper.getOnlineData(tableName, pageQuery.build(), wrapper);
		List<Map> records = page.getRecords();
		Map<String, Object> onlineField = getOnlineForm(tableId);
		TableVo tableVo = (TableVo) onlineField.get("info");
		List<OnlFieldVo> columnsList = tableVo.getColumnsVo();
		for (Map map : records) { //对longblob数据类型做特殊处理
			for (OnlFieldVo onlineFieldVo : columnsList) {
				if ( StringUtils.equalsAny(onlineFieldVo.getColumnType(), "longblob")) {
					Object blob = (Object) map.get(onlineFieldVo.getColumnName());
					String content;
					try {
						if(ObjectUtils.isNotEmpty(blob)) {
							content = new String((byte[])blob,"utf-8");
						}
						else {
							content = "";
						}
						map.put(onlineFieldVo.getColumnName(), content); // 更新longblob内容
					} catch (UnsupportedEncodingException e) {
						e.printStackTrace();
					}		
				}	
			}
		}
		page.setRecords(records);
		return TableDataInfo.build(page,onlineField);
	}

	@Override
	public int addOrUpdateOnlineData(Long tableId, String tableName, Map<String, Object> map) {
		GenTable table = genTableService.selectGenTableById(tableId);
		List<GenTableColumn> columnsList = table.getColumns();
		String pkName="";
		//获取pk
		for (GenTableColumn genTableColumn : columnsList) {
			String isPk = (String) genTableColumn.getIsPk();
			if (StringUtils.equals(isPk, "1")) {
				pkName = genTableColumn.getColumnName();
			}
		}
		if (map.containsKey(pkName) && ObjectUtils.isNotEmpty(map.get(pkName))) {//修改
			//对更新时间与更新人进行处理
	        if (map.containsKey("update_by")) {
	            map.put("update_by", LoginHelper.getUserId());
	        }
	        // 获取当前日期和时间
	        LocalDateTime now = LocalDateTime.now();
	        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
	        String formattedDateTime = now.format(formatter);
	        if (map.containsKey("update_time")) {
	        	map.put("update_time",  formattedDateTime);
	        }
			if (map.containsKey("tenant_id")) {
	            map.remove("tenant_id");
	        }
	        if (map.containsKey("create_dept")) {
	            map.remove("create_dept");
	        }
	        if (map.containsKey("create_time")) {
	        	map.remove("create_time");
	        }
	        if (map.containsKey("create_by")) {
	        	map.remove("create_by");
	        }
	        
			Map<String, Object> whereid = new HashMap<String, Object>();
			whereid.put(pkName, map.get(pkName));
			// 直接删除pkid
	        if (map.containsKey(pkName)) {
	            map.remove(pkName);
	        }
	        
			return onlineMapper.dynamicUpdate(tableName, map, whereid);
		}
		else { //新增
			long timestamp = System.nanoTime();
			//map.put(pkName, timestamp);
			// 获取当前日期和时间
	        LocalDateTime now = LocalDateTime.now();
	        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
	        String formattedDateTime = now.format(formatter);
	        map.put("tenant_id", TenantHelper.getTenantId());
	        map.put("create_by", LoginHelper.getUserId());
	        map.put("create_time", formattedDateTime);
	        map.put("create_dept", LoginHelper.getDeptId());
			return onlineMapper.insertDynamic(tableName, map);
		}
        
	}

	 @Override
	    @Transactional
	    public void deleteOnlineData(Long tableId, String tableName, List<Long> ids) {
	        // 参数校验
	        if (CollectionUtils.isEmpty(ids)) {
	            throw new IllegalArgumentException("删除ID不能为空");
	        }
	        
	        GenTable table = genTableService.selectGenTableById(tableId);
			List<GenTableColumn> columnsList = table.getColumns();
			String pkName="";
			//获取pk
			for (GenTableColumn genTableColumn : columnsList) {
				String isPk = (String) genTableColumn.getIsPk();
				if (StringUtils.equals(isPk, "1")) {
					pkName = genTableColumn.getColumnName();
				}
			}

	        // 执行删除
	        onlineMapper.deleteDynamicTable(tableName, pkName, ids);
	    }

	@Override
	public Map<String, Object> getOnlineData(Long tableId, String tableName, Long id) {
		// 参数校验
	    if (id == null) {
	        throw new IllegalArgumentException("ID不能为空");
	    }
	    
	    // 获取表结构信息
	    GenTable table = genTableService.selectGenTableById(tableId);
	    List<GenTableColumn> columnsList = table.getColumns();
	    
	    // 提取主键列名
	    String pkName = columnsList.stream()
	        .filter(column -> "1".equals(column.getIsPk()))
	        .findFirst()
	        .map(GenTableColumn::getColumnName)
	        .orElseThrow(() -> new RuntimeException("表" + tableName + "无主键"));
	    
	    // 执行动态查询
	    Map<String, Object> result = onlineMapper.selectDynamicTableById(tableName, pkName, id);
	    
	    // 获取表的字段信息
	    Map<String, Object> onlineField = getOnlineForm(tableId);
	    TableVo tableVo = (TableVo) onlineField.get("info");
	    List<OnlFieldVo> columns = tableVo.getColumnsVo();
	    
	    // 对longblob数据类型做特殊处理
	    for (OnlFieldVo fieldVo : columns) {
	        if ("longblob".equals(fieldVo.getColumnType())) {
	            Object blob = result.get(fieldVo.getColumnName());
	            if (blob instanceof byte[]) {
	                try {
	                    String content = new String((byte[]) blob, "utf-8");
	                    result.put(fieldVo.getColumnName(), content); // 更新longblob内容
	                } catch (UnsupportedEncodingException e) {
	                    e.printStackTrace();
	                }
	            }
	        }
	    }
	    
	    return result;
	}
}
